package maths;

public class Vector3d {
	
	private double x;
	private double y;
	private double z;
	
	public Vector3d(){
		this.x = 0;
		this.y = 0;
		this.z = 0;
	}
	
	public Vector3d(double[] p){
		this.x = p[0];
		this.y = p[1];
		this.z = p[2];
	}
	
	public Vector3d(double x,double y, double z){
		this.x = x;
		this.y = y;
		this.z = z;
	}
	
	/** sets the value of this vector to itself + the values of vector2 **/
	public void add(Vector3d vector2){
		this.setX(this.x + vector2.getX());
		this.setY(this.y + vector2.getY());
		this.setZ(this.z + vector2.getZ());
	}
	
	/** sets the value of this vector to itself - the values of vector2 **/
	public void sub(Vector3d vector2){
		this.setX(this.x - vector2.getX());
		this.setY(this.y - vector2.getY());
		this.setZ(this.z - vector2.getZ());
	}
	
	/** multiplies the values of this vector by scalar x **/
	public void multiply(double x){
		this.setX(this.x * x);
		this.setY(this.y * x);
		this.setZ(this.z * x);
	} 
	
	/** returns the dot product of this vector and vector 2 **/
	public double dot(Vector3d vector2){
		double p = this.x*vector2.getX()+this.y*vector2.getY()+this.z*vector2.getZ();
		return p;
	}
	
	/** sets this vector to the cross product of Vector 1 vector 2 **/
	public void cross(Vector3d vector1, Vector3d vector2){
		double value = Double.NaN;
		
			value = vector1.getY()*vector2.getZ() - vector1.getZ()*vector2.getY();
			this.setX(value);
		
			value = vector1.getZ()*vector2.getX() - vector1.getX()*vector2.getZ();
			this.setY(value);
		
			value = vector1.getX()*vector2.getY() - vector1.getY()*vector2.getX();
			this.setZ(value);	
	}
	
	
	/** returns the length of this vector**/
	public double length(){
		double length = Math.sqrt(this.x*this.x + this.y*this.y +this.z*this.z);
		return length;
	}
	/** returns the squared length of this vector**/
	public double lengthSquared(){
		double lengthSquared = this.x*this.x + this.y*this.y +this.z*this.z;
		return lengthSquared;
	}	
	/** returns the angle in radians between this vector and vector2 **/	
	public double angle(Vector3d vector2){
		double angle = Math.acos(this.dot(vector2)/(this.length()*vector2.length()));
		return angle;
	}
	
	/** normalizes this vector **/
	public void normalize(){
		double scale = 1/this.length();
		this.setX(scale*this.x);
		this.setY(scale*this.y);
		this.setZ(scale*this.z);
	}

	/** sets this vector to the normalisation of the supplied vector **/
	public void normalize(Vector3d vector){
		double scale = 1/vector.length();
		this.setX(scale*vector.x);
		this.setY(scale*vector.y);
		this.setZ(scale*vector.z);
	}
	
	public double getX() {
		return this.x;
	}
	public void setX(double x) {
		this.x = x;
	}
	public double getY() {
		return y;
	}
	public void setY(double y) {
		this.y = y;
	}
	public double getZ() {
		return z;
	}
	public void setZ(double z) {
		this.z = z;
	}
	public String toString(){
		String vector = "("+this.x+","+this.y+","+this.z+")";
		return vector;
	}
	public double[] toArray(){
		double[] components = new double[3];
		components[0] = this.getX();
		components[1] = this.getY();
		components[2] = this.getZ();
		return components;
	}
}
